package com.hqd.ch03.v5.reader;

import com.hqd.ch03.v5.config.BeanDefinition;
import com.hqd.ch03.v5.config.MutablePropertyValues;
import com.hqd.ch03.v5.io.Resource;
import com.hqd.ch03.v5.registry.BeanDefinitionRegistry;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

/**
 * XML方式读取Bean定义
 */
public class XmlBeanDefinitionReader implements BeanDefinitionReader {
    private BeanDefinitionRegistry beanDefinitionRegistry;

    public XmlBeanDefinitionReader(BeanDefinitionRegistry beanDefinitionRegistry) {
        this.beanDefinitionRegistry = beanDefinitionRegistry;
    }


    @Override
    public void loadBeanDefinition(Resource resource) {
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(resource.getInputStream());
            Element rootElement = document.getRootElement();
            List<Element> beanEles = rootElement.elements("bean");
            beanEles.forEach(beanEle -> {
                BeanDefinition bd = parseBeanEle(beanEle);
                beanDefinitionRegistry.registerBeanDefinition(bd.getId(), bd);
            });
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 转换bean节点
     *
     * @param element
     * @return
     */
    private BeanDefinition parseBeanEle(Element element) {
        BeanDefinition bd = new BeanDefinition();
        bd.setScope(element.attributeValue("scope"));
        bd.setId(element.attributeValue("id"));
        String lazyInit = element.attributeValue("lazy-init");
        bd.setLazyInit(StringUtils.isBlank(lazyInit) ? true : Boolean.valueOf(lazyInit));
        bd.setBeanClass(element.attributeValue("class"));
        bd.setProperties(parsePropertyEles(element.elements("property")));
        return bd;
    }

    /**
     * 转换bean下的property节点
     *
     * @param elements
     * @return
     */
    private MutablePropertyValues parsePropertyEles(List<Element> elements) {
        if (CollectionUtils.isNotEmpty(elements)) {
            MutablePropertyValues propertyValues = new MutablePropertyValues();
            elements.forEach(element -> {
                propertyValues.addProperty(element.attributeValue("name"), element.attributeValue("value"));
            });
            return propertyValues;
        }
        return null;
    }
}
